// https://leetcode.cn/problems/range-sum-query-mutable/
// Created by ade on 2022/10/20.
//

class NumArray {
private:
    // 参考：https://leetcode.cn/problems/range-sum-query-mutable/solution/qu-yu-he-jian-suo-shu-zu-ke-xiu-gai-by-l-76xj/
    vector<int> segmentTree;
    int len;

    /**
     * @param node 线段树节点
     * @desc 构建线段树
     */
    void build(int node, int l, int r, vector<int> &nums) {
        if (l == r) {
            segmentTree[node] = nums[l];
            return;
        }
        int m = getMid(l, r);
        build(node * 2 + 1, l, m, nums);
        build(node * 2 + 2, m + 1, r, nums);
        segmentTree[node] = segmentTree[node * 2 + 1] + segmentTree[node * 2 + 2];
    }

    void change(int index, int val, int node, int l, int r) {
        if (l == r) {
            segmentTree[node] = val;
            return;
        }
        int m = getMid(l, r);
        if (index <= m) {
            change(index, val, node * 2 + 1, l, m);
        } else {
            change(index, val, node * 2 + 2, m + 1, r);
        }
        segmentTree[node] = segmentTree[node * 2 + 1] + segmentTree[node * 2 + 2];
    }

    /**
     *
     * @param l 需要求的开始位置
     * @param r 需要求的结束位置
     * @param node node节点
     * @param start 区间开始
     * @param end 区间结束
     * @return
     */
    int range(int l, int r, int node, int start, int end) {
        if (l == start && r == end) {
            return segmentTree[node];
        }
        int m = getMid(start, end);
        if (r <= m) {
            return range(l, r, node * 2 + 1, start, m);
        } else if (l > m) {
            return range(l, r, node * 2 + 2, m + 1, end);
        } else {
            return range(l, m, node * 2 + 1, start, m) + range(m + 1, r, node * 2 + 2, m + 1, end);
        }
    }

    int getMid(int l, int r) {
        return l + (r - l) / 2;
    }

public:
    NumArray(vector<int> &nums) {
        len = nums.size();
        segmentTree = vector<int>(len * 4);
        build(0, 0, len - 1, nums);
    }

    void update(int index, int val) {
        change(index, val, 0, 0, len - 1);
    }

    int sumRange(int left, int right) {
        return range(left, right, 0, 0, len - 1);
    }
};
